package com.yhy.wxzn.wcs.device.rgv.bean;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.util.StrUtil;
import com.yhy.wxzn.common.utils.SpringUtil;
import com.yhy.wxzn.wcs.device.plc.bean.FourCarPlc;
import com.yhy.wxzn.wcs.device.plc.bean.HoistPlc;
import com.yhy.wxzn.wcs.device.plc.bean.XJPHoistPlc;
import com.yhy.wxzn.wcs.device.plc.xj.XjPlcDriver;
import com.yhy.wxzn.wcs.device.rgv.FourWayRgvTaskExecuteThread;
import com.yhy.wxzn.wcs.device.rgv.core.lock.LockNodeManager;
import com.yhy.wxzn.wcs.device.rgv.enums.NodeType;
import com.yhy.wxzn.wcs.entity.WcsDeviceInfo;
import com.yhy.wxzn.wcs.entity.WcsFourWayTask;
import com.yhy.wxzn.wcs.entity.WcsTask;
import com.yhy.wxzn.wcs.enums.TaskType;
import com.yhy.wxzn.wcs.service.impl.WcsDeviceInfoServiceImpl;
import com.yhy.wxzn.wcs.service.impl.WcsMapInfoServiceImpl;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

import static com.yhy.wxzn.wcs.SystemInit.*;


@Slf4j
@Getter
@Setter
public class FourWayRgv extends BaseRgv {

    private WcsDeviceInfo deviceInfo;


    private FourCarPlc fourCarPlc;

    private XjPlcDriver xjPlcDriver;

    private FourWayRgvTaskExecuteThread fourWayRgvExecuteTaskThread;


    /**
     * 当前车辆需要的资源
     */
    private volatile Set<FourWayRgv> waitingForReleaseResource =  new ConcurrentHashSet<>();


    @Override
    public String toString() {
        return getName();
    }

    /**
     * 小车分配的任务
     */
    private volatile WcsTask curTask;

    @Override
    public String getName() {
        return deviceInfo.getDeviceName();
    }


    /**
     * 获取当前位置
     * @return
     */
    @Override
    public Node getCurLocation() {
        if (Local_Test){
            WcsDeviceInfo rgvInfo = SpringUtil.getBean(WcsDeviceInfoServiceImpl.class).getById(deviceInfo.getId());
            WcsMapInfoServiceImpl bean = SpringUtil.getBean(WcsMapInfoServiceImpl.class);
            return  bean.getNode(Node.parseNode(rgvInfo.getLocation()));
        }
        String twoCode = this.fourWayRgvExecuteTaskThread.getFourCarPlc().getTwoCode();
        if (StrUtil.isEmpty(twoCode)){
            String msg = String.format("小车%s,未扫到地码",getName());
            log.error(msg);
            throw new RuntimeException(msg);
        }
        Node res = null;
        WcsMapInfoServiceImpl wcsMapInfoService = SpringUtil.getBean(WcsMapInfoServiceImpl.class);
        List<Node> nodes = wcsMapInfoService.getMapByGroundCode(twoCode);
        if (CollUtil.isEmpty(nodes)){
            String msg = String.format("地码：%s,在数据库中不存在", twoCode);
            log.error(msg);
            throw new RuntimeException(msg);
        }

        if (nodes.size() == 1){
            res = nodes.get(0);
        }else {
            //数据库中提升机所有的层的地码要一样
            //提升机
            XJPHoistPlc hoistPlc = liferPlcMap.get(liferToDeviceIdMap.get(new Lifter(nodes.get(0))));
            int floor = hoistPlc.getLayer();
            for (Node node : nodes) {
                if (node.getZ() == floor){
                    res = node;
                    break;
                }
            }

            if (res == null){
                nodes.get(0).setZ(floor);

                throw new RuntimeException(nodes.get(0).toString()+"数据库中的地码不正确");
            }
        }

        return res;
    }

    /**
     * 获取当前位置，比对数据库位置，不同则，同步数据库并清除锁定节点
     * @return
     */
    @Override
    public Node getCurLocationAndRefreshRgvLocation() {
        Node curLocation = getCurLocation();
        if (Lifter_Connection){
            if ( curLocation.getNodeType() == NodeType.L){
                SpringUtil.getBean(WcsDeviceInfoServiceImpl.class).refreshRgvLocation(deviceInfo.getId(),new Coord(curLocation));
            }else {
                freshRgvInfo(new Coord(curLocation));
            }
        }else {
            freshRgvInfo(new Coord(curLocation));
        }
        return curLocation;
    }



    @Override
    public void freshRgvInfo(Coord location) {
        SpringUtil.getBean(WcsDeviceInfoServiceImpl.class).refreshRgvLocation(deviceInfo.getId(),location);
        LockNodeManager.updateLocationLock(this,location);
    }




}
